#include "./handler_task.h"
#include "../pub_service/ota_service.h"
#include "../ice_driver/ctrl.h"
#include "../ice_driver/sensor.h"
#include "../pub_driver/cmd_can.h"
#include "./draw_task.h"
#include "./make_ice_task.h"

namespace ice_task {

using namespace pub_service;
using namespace pub_driver;
using namespace conn;
using namespace ice_driver;

HandlerTask handlerTask;

void HandlerTask::init_start() {
    m_mq.init();
    start();
}

static void on_parts_ctrl(const Frame &frame) {
    uint8_t parts, val;
    Error err = frame.parse(parts, val);
    if (err) {
        goto finish;
    }

    if ((parts > 5) || (val > 1)) {
        err = ec::pub::INVALID;
        goto finish;
    }   
    drawTask.stop();
    makeIceTask.stop();
    switch (val) {
        case 0: ctrl.open( static_cast<Ctrl::Parts>(parts) ); break;
        case 1: ctrl.close( static_cast<Ctrl::Parts>(parts) ); break;
    }

finish:
    cmdCAN.fast_res(frame, err);
}

static void on_draw_make_ctrl(const Frame &frame) {
    uint8_t value;
    Error err = frame.parse(value);
    if (err) {
        goto finish;
    }
    
    switch (value) {
        case 0: drawTask.idle(); break;
        case 1: drawTask.stop(); break;
        case 2: makeIceTask.idle(); break;
        case 3: makeIceTask.stop(); break;
        default: err = ec::pub::INVALID; break;
    }
finish:
    cmdCAN.fast_res(frame, err);
}

static void on_drop_ice_ctrl(const Frame &frame) {
    uint8_t sec;
    Error err = frame.parse(sec);
    if (err) {
        goto finish;
    }
    ctrl.stir_motor_open();
    ctrl.open(Ctrl::Parts::DROP_ICE);
    osDelay(sec * 1000);
    ctrl.stir_motor_close();
    ctrl.close(Ctrl::Parts::DROP_ICE);
finish:
    cmdCAN.fast_res(frame, err);
}

void HandlerTask::run() {

    Frame frame;
    for (;;) {
        m_mq.poll(frame);
        task_info.seq = frame.seq_cmd();
        task_info.cmd = frame.cmd();

        switch (frame.cmd()) {
            case proto::ice::DROP_ICE_CTRL: on_drop_ice_ctrl(frame); break;
            case proto::ice::DRAW_MAKE_CTRL: on_draw_make_ctrl(frame); break;
            case proto::ice::PARTS_CTRL: on_parts_ctrl(frame); break;
            case proto::pub::OTA_START: pub_service::ota_start(frame); break;
            case proto::pub::OTA_TRANSLATE: pub_service::ota_translate(frame); break;
            case proto::pub::OTA_COMPLETE: pub_service::ota_complete(frame); break;
        }
    
        task_info.reset();
    }
}

}

